package com.yhn.bubblevideo.user.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yhn.bubblevideo.common.enums.BaseErrorCode;
import com.yhn.bubblevideo.common.exception.BusinessException;
import com.yhn.bubblevideo.common.exception.ThrowUtils;
import com.yhn.bubblevideo.model.domain.Follow;
import com.yhn.bubblevideo.model.dto.req.common.DeleteRequest;
import com.yhn.bubblevideo.model.dto.req.follow.FollowAddRequestDTO;
import com.yhn.bubblevideo.model.dto.req.follow.FollowEditRequestDTO;
import com.yhn.bubblevideo.model.dto.req.follow.FollowQueryRequestDTO;
import com.yhn.bubblevideo.model.dto.resp.FollowRespDTO;
import com.yhn.bubblevideo.model.dto.resp.UserRespDTO;
import com.yhn.bubblevideo.user.mapper.FollowMapper;
import com.yhn.bubblevideo.user.service.FollowService;
import com.yhn.bubblevideo.user.service.UserService;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.yhn.bubblevideo.common.constant.CommonConstant.MAX_PAGE_SIZE;

/**
 * @author yhnyhn123
 * @description 针对表【follow(关注表)】的数据库操作Service实现
 * @createDate 2024-11-21 13:33:34
 */
@Service
public class FollowServiceImpl extends ServiceImpl<FollowMapper, Follow>
        implements FollowService {

    @Resource
    private UserService userService;


    /**
     * 分页查询
     */
    @Override
    public Page<FollowRespDTO> queryPage(FollowQueryRequestDTO requestParam) {
        if (requestParam == null) {
            throw new BusinessException(BaseErrorCode.PARAMS_ERROR);
        }
        long current = requestParam.getCurrent();
        long size = requestParam.getPageSize();
        // 限制爬虫
        ThrowUtils.throwIf(size > MAX_PAGE_SIZE, BaseErrorCode.PARAMS_ERROR);
        Page<Follow> followPage = this.page(new Page<>(current, size),
                this.getQueryWrapper(requestParam));
        Page<FollowRespDTO> followRespPage = new Page<>(current, size, followPage.getTotal());
        List<FollowRespDTO> followVO = this.getFollowVO(followPage.getRecords());
        followRespPage.setRecords(followVO);
        return followRespPage;
    }

    @Override
    public LambdaQueryWrapper<Follow> getQueryWrapper(FollowQueryRequestDTO requestParam) {

        if (requestParam == null) {
            return null;
        }

        LambdaQueryWrapper<Follow> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//        lambdaQueryWrapper
//                .like(requestParam.getFollowName() != null, Follow::get, requestParam.getName());
        return lambdaQueryWrapper;
    }

    /**
     * 获取脱敏对象集合
     *
     * @param followList 查询请求
     * @return 脱敏对象集合
     */
    @Override
    public List<FollowRespDTO> getFollowVO(List<Follow> followList) {
        if (CollUtil.isEmpty(followList)) {
            return new ArrayList<>();
        }
        return followList.stream().map(this::getFollowVO).collect(Collectors.toList());
    }


    /**
     * 将对象转化为脱敏对象
     *
     * @param follow 原对象
     * @return 脱敏对象
     */
    @Override
    public FollowRespDTO getFollowVO(Follow follow) {
        if (follow == null) {
            return null;
        }
        FollowRespDTO followResp = new FollowRespDTO();

        BeanUtils.copyProperties(follow, followResp);
        return followResp;
    }

    /**
     * 根据ID获取信息
     *
     * @param id id
     * @return 实体信息
     */
    @Override
    public FollowRespDTO getInfoById(Long id) {
        Follow follow = baseMapper.selectById(id);
        if (follow == null) {
            throw new BusinessException(BaseErrorCode.NOT_FOUND_ERROR, "没有对应的信息");
        }
        return getFollowVO(follow);
    }

    /**
     * 保存信息
     *
     * @param requestParam 添加请求
     * @return 新生成的ID
     */
    @Override
    @Transactional
    public Long saveFollow(FollowAddRequestDTO requestParam) {
        if (requestParam == null) {
            throw new BusinessException(BaseErrorCode.PARAMS_ERROR);
        }
        Long followId = requestParam.getFollowId();
        UserRespDTO user = userService.getInfoById(followId);
        if (user == null) {
            throw new BusinessException("你关注的用户不存在");
        }
        LambdaQueryWrapper<Follow> queryWrapper = Wrappers.lambdaQuery(Follow.class)
                .eq(Follow::getFansId, requestParam.getFansId())  // 如果 fansId 不为空，则添加 eq 条件
                .and(wrapper -> wrapper
                        .like(Follow::getFollowId, requestParam.getFollowId())); // 使用 and 方法嵌套条件
        baseMapper.selectCount(queryWrapper);
        if (baseMapper.selectCount(queryWrapper) > 0) {
            throw new BusinessException("你已关注了该用户");
        }
        Follow follow = new Follow();
        BeanUtils.copyProperties(requestParam, follow);
        boolean result = this.save(follow);
        ThrowUtils.throwIf(!result, BaseErrorCode.OPERATION_ERROR);
        return follow.getId();
    }


    /**
     * 修改信息
     *
     * @param requestParam 修改请求
     * @return 是否修改成功
     */
    @Override
    @Transactional
    public Boolean updateFollow(FollowEditRequestDTO requestParam) {
        if (requestParam == null || requestParam.getId() <= 0) {
            throw new BusinessException(BaseErrorCode.PARAMS_ERROR);
        }
        Follow follow = new Follow();
        BeanUtils.copyProperties(requestParam, follow);
        long id = requestParam.getId();
        // 判断是否存在
        Follow oldFollow = this.getById(id);
        ThrowUtils.throwIf(oldFollow == null, BaseErrorCode.NOT_FOUND_ERROR);
        boolean result = this.updateById(follow);
        ThrowUtils.throwIf(!result, BaseErrorCode.OPERATION_ERROR);
        return true;
    }

    /**
     * 删除信息
     *
     * @param deleteRequest 删除请求
     * @return 是否修改成功
     */
    @Override
    @Transactional
    public Boolean deleteById(DeleteRequest deleteRequest) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(BaseErrorCode.PARAMS_ERROR);
        }
        long id = deleteRequest.getId();
        // 判断是否存在
        boolean b = this.removeById(id);
        ThrowUtils.throwIf(!b, BaseErrorCode.NOT_FOUND_ERROR);
        return true;
    }

    @Override
    public List<UserRespDTO> getFollowingList(Long userId) {
        //获取关注列表的所有ID
        LambdaQueryWrapper<Follow> queryWrapper = Wrappers.lambdaQuery(Follow.class)
                .eq(Follow::getFansId, userId);
        List<Follow> list = baseMapper.selectList(queryWrapper);
        //返回用户关注信息
        return list.stream().map(follow -> userService.getInfoById(follow.getFollowId())).collect(Collectors.toList());
    }

    @Override
    public List<UserRespDTO> getFansList(Long userId) {
        //获取粉丝列表的所有ID
        LambdaQueryWrapper<Follow> queryWrapper = Wrappers.lambdaQuery(Follow.class)
                .eq(Follow::getFollowId, userId);
        List<Follow> list = baseMapper.selectList(queryWrapper);
        //返回用户粉丝列表信息
        return list.stream().map(follow -> userService.getInfoById(follow.getFollowId())).collect(Collectors.toList());
    }


}




